package cn.ytxy.double_system_data_visualization_demo.user.controller;

import cn.ytxy.double_system_data_visualization_demo.base.response.JsonResult;
import cn.ytxy.double_system_data_visualization_demo.base.response.StatusCode;
import cn.ytxy.double_system_data_visualization_demo.user.pojo.dto.UserLoginParam;
import cn.ytxy.double_system_data_visualization_demo.user.pojo.dto.UserQuery;
import cn.ytxy.double_system_data_visualization_demo.user.pojo.dto.UserSaveParam;
import cn.ytxy.double_system_data_visualization_demo.user.pojo.entity.User;
import cn.ytxy.double_system_data_visualization_demo.user.pojo.vo.UserVO;
import cn.ytxy.double_system_data_visualization_demo.user.service.UserService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import springfox.documentation.spring.web.json.Json;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/v1/user")
public class UserController {
    @Autowired
    UserService userService;

    /**
     * 用户登录
     *
     * @param userLoginParam 登录请求参数（包含用户名和密码）
     *                       //     * @param session        HTTP会话对象，用于保存用户登录状态
     * @return 登录结果封装为 JsonResult
     */
    @ApiOperation("管理员账号登陆")
    @PostMapping("/login")
    public JsonResult login(@RequestBody UserLoginParam userLoginParam, HttpServletRequest request) {
        // 记录非敏感日志信息
        log.info("Controller层-用户登录请求参数，用户名：{}", userLoginParam.getUsername());

        // 输入校验
        if (userLoginParam == null ||
                userLoginParam.getUsername() == null || userLoginParam.getUsername().trim().isEmpty() ||
                userLoginParam.getPassword() == null || userLoginParam.getPassword().trim().isEmpty()) {
            return new JsonResult(StatusCode.VALIDATE_ERROR, "用户名或密码不能为空");
        }
        // 执行登录逻辑
        UserVO userVO = userService.login(userLoginParam);

        // 避免空指针，增强健壮性
        if (userVO == null) {
            return new JsonResult(StatusCode.DATA_UNEXISTS, "登录失败，用户信息不存在");
        }

        return JsonResult.ok(userVO);

    }


    /**
     * 获取当前管理员信息
     * 此方法通过 HttpSession 获取当前管理员的用户信息
     * 使用 @GetMapping 注解指定 HTTP GET 请求的处理方法，路径为 "currentUser"
     *
     * @param session HTTP 会话对象，用于获取当前会话中的用户信息
     *                使用 @ApiIgnore 注解忽略 HttpSession 参数，因为它不是由用户提供的数据
     * @return 返回包含当前管理员信息的 JsonResult 对象
     */
    @ApiOperation("获取当前管理员")
    @GetMapping("currentUser")
    public JsonResult currentUser(@ApiIgnore HttpSession session) {
        // 在服务器的内存中,获取会话对象
        // 使用 @ApiIgnore 注解忽略 HttpSession 参数，因为它不是由用户提供的数据
        UserVO user = (UserVO) session.getAttribute("username");

        // 返回当前用户信息，如果 session 中没有用户信息，则返回 null
        return JsonResult.ok(user);
    }


    /**
     * 查询用户
     * <p>
     * 该方法通过接收UserQuery对象作为查询条件，从用户服务中获取满足条件的用户列表
     * 主要用于处理用户查询请求，将查询参数传递给业务服务层，并返回查询结果
     *
     * @param userQuery 用户查询条件封装对象，通过@Valid注解进行参数有效性校验
     * @return 返回一个包含用户信息列表的JsonResult对象，表示查询结果
     */
    @ApiOperation("查询所有用户")
    @GetMapping("/select")
    public JsonResult selectUser(UserQuery userQuery) {
        // 记录Controller层查询用户请求的参数信息
        log.info("Controller层-查询用户请求参数：{}", userQuery);

        // 调用UserService中的selectUser方法，传入查询条件，并获取查询结果列表
        List<UserVO> list = userService.selectUser(userQuery);

        // 返回查询结果，使用JsonResult.ok表示操作成功，并将用户列表作为结果返回
        return JsonResult.ok(list);
    }


    /**
     * 保存用户信息
     * <p>
     * 该方法通过POST请求接收用户数据，并将其实例化为UserSaveParam对象
     * 使用了@Valid注解来确保传入的参数符合规范，提高了数据的准确性
     *
     * @param userSaveParam 用户保存参数，包含需要保存的用户信息
     * @return 返回JsonResult对象，表示操作结果
     */
    @ApiOperation("保存用户")
    @PostMapping("/save")
    // 前端传过来的数据已经由qs(QueryString)转为了查询字符串格式
    // 所以不需要使用@RequestBody注解进行映射了
    public JsonResult saveUser(@Valid UserSaveParam userSaveParam) {
        // 记录日志，输出用户保存参数信息
        log.debug("保存用户,userSaveParam={}", userSaveParam);
        // 调用userService的saveUser方法，执行用户信息保存操作
        userService.saveUser(userSaveParam);
        // 返回操作成功的JsonResult对象
        return JsonResult.ok();
    }


    /**
     * 删除用户
     * <p>
     * 此方法通过用户ID删除特定的用户信息它使用POST请求，并在请求路径中包含用户ID
     * 使用此方法需要注意确保操作权限和数据完整性，避免非法或错误地删除用户
     *
     * @param userId 要删除的用户的ID，通过URL路径参数传递
     * @return 返回一个JsonResult对象，表示删除操作的结果状态
     */
    @ApiOperation("根据id删除用户")
    @PostMapping("/delete/{userId}")
    public JsonResult deleteUser(@PathVariable Long userId) {
        // 记录删除用户操作的日志，包括用户ID
        log.debug("删除用户,userId={}", userId);
        // 调用用户服务中的删除方法，传入用户ID
        userService.deleteUser(userId);
        // 返回操作成功的结果状态
        return JsonResult.ok();
    }


    /**
     * 处理加分请求
     * <p>
     * 该方法通过POST请求接收用户ID、加分点数和原因，并调用用户服务执行加分操作
     * 加分操作完成后，返回操作成功的响应结果
     *
     * @param userId 要加分的用户ID，通过URL路径参数传递
     * @param points 要增加的分数，通过请求参数传递
     * @param reason 加分的原因，通过请求参数传递
     * @return 返回JsonResult对象，表示操作结果
     */
    @ApiOperation("根据id增加积分")
    @PostMapping("/addScore/{userId}")
    public JsonResult addScore(@PathVariable Long userId, @RequestParam Integer points, @RequestParam String reason) {

        // 记录加分日志
        log.debug("加分业务：userId={},points={},reason={}", userId, points, reason);
        // 调用用户服务执行加分操作
        userService.addScore(userId, points, reason);
        // 返回加分成功的结果
        return JsonResult.ok();
    }


    /**
     * 处理减分请求
     * <p>
     * 该方法通过POST请求接收用户ID、减分点数和原因，并调用用户服务执行减分操作
     * 减分操作完成后，返回操作成功的响应结果
     *
     * @param userId 要减分的用户ID，通过URL路径参数传递
     * @param points 要减少的分数，通过请求参数传递
     * @param reason 减分的原因，通过请求参数传递
     * @return 返回JsonResult对象，表示操作结果
     */
    @ApiOperation("根据id减少积分")
    @PostMapping("/subtractScore/{userId}")
    public JsonResult subtractScore(@PathVariable Long userId, @RequestParam Integer points, @RequestParam String reason) {

        // 记录减分业务的日志，提高可追踪性
        log.debug("减分业务：userId={},score={},reason={}", userId, points, reason);

        // 调用用户服务中的减分方法，执行减分操作
        userService.subtractScore(userId, points, reason);

        // 返回操作成功的响应结果
        return JsonResult.ok();
    }

}